// ====================Util====================

Bitmap.prototype.drawIcon = function (iconIndex, x, y, w, h) {
    const bitmap = ImageManager.loadSystem("IconSet");
    const pw = ImageManager.iconWidth;
    const ph = ImageManager.iconHeight;
    const sx = (iconIndex % 16) * pw;
    const sy = Math.floor(iconIndex / 16) * ph;
    this.blt(bitmap, sx, sy, pw, ph, x, y, w, h);
};
/**
 * 绘制脸图
 */
Bitmap.prototype.drawFace = function (faceName, faceIndex, x, y, width, height) {
    width = width || ImageManager.faceWidth;
    height = height || ImageManager.faceHeight;
    const bitmap = ImageManager.loadFace(faceName);
    const pw = ImageManager.faceWidth;
    const ph = ImageManager.faceHeight;
    const sw = Math.min(width, pw);
    const sh = Math.min(height, ph);
    const dx = Math.floor(x + Math.max(width - pw, 0) / 2);
    const dy = Math.floor(y + Math.max(height - ph, 0) / 2);
    const sx = (faceIndex % 4) * pw + (pw - sw) / 2;
    const sy = Math.floor(faceIndex / 4) * ph + (ph - sh) / 2;
    bitmap.addLoadListener(() => {
        this.blt(bitmap, sx, sy, sw, sh, dx, dy);
    })
};

/**
 * 富文本处理
 */
Bitmap.prototype.drawTextPlus = function (text, x, y, maxWidth = 200, maxHeight = 200) {
    const textState = {
        ox: x,
        oy: y,
        x: x,
        y: y,
        width: maxWidth,
        height: maxHeight,
        lineHeight: 22,
        content: text,
        line: ""
    }
    let t, count = 0;
    while (textState.content.length > 0) {
        if (count > 10000) {
            throw new Error("死循环或循环次数超过10000，位于CardCore.js-富文本处理！");
        }
        t = textState.content.substring(0, 1);
        if (t === "<") {
            this.processEscapeCharacter(textState);
            continue;
        }
        this.addCharacter(textState);
        count++;
    }
    return textState.obj;
};

/**
 * 处理转义字符
 * @param {Object} textState 文字声明
 */
Bitmap.prototype.processEscapeCharacter = function (textState) {
    const regExp = /^<([^<>:]+)(:?)([^>]*)>/;
    const match = regExp.exec(textState.content);
    if (!match) {
        this.addCharacter(textState);
        return;
    }
    switch (match[1]) {
        // 判断换行
        case "br": {
            this.newLine(textState);
            break;
        }
        // 绘制图标
        case "i": {
            const iconIndex = Number(match[3]);
            const iconWidth = ImageManager.iconWidth;
            // 判断宽度是否超过限定宽度
            if (textState.x + iconWidth > textState.width) {
                this.newLine(state);
            }
            const y = textState.y + (textState.lineHeight - ImageManager.iconHeight) / 2;
            this.drawIcon(iconIndex, textState.x, y);
            textState.x += iconWidth;
            textState.ox = textState.x;
            this.addLine(textState);
            break;
        }
        // 颜色
        case "c": {
            this.textColor = match[3];
            break;
        }
        // 代码
        case "code": {
            const code = match[3];
            const f = new Function(`return ${code}`);
            try {
                const result = f();
                textState.content = textState.content.replace(regExp, result);
                // textState.content = result + textState.content;
            } catch (e) {
                console.error(e);
            }
            break;
        }
        default: {
            this.addCharacter(textState);
            return;
        }
    }
    // 移除已处理的字符
    textState.content = textState.content.replace(regExp, "");
};

/**
 * 添加字符
 * @param {Object} textState 文字声明
 */
Bitmap.prototype.addCharacter = function (textState) {
    const t = textState.content[0];
    // TODO 宽度测量性能开销很大，做缓存
    const w = this.measureTextWidth(t);
    const punctuation = [",", ".", "!", "?", "，", "。", "！", "？"];
    // 标点符号不换行
    if (!punctuation.includes(t)) {
        // 判断是否超过限定宽度
        if (textState.x + w > textState.width) {
            this.newLine(textState);
        }
    }
    this.drawText(t, textState.x, textState.y, w, textState.lineHeight);
    textState.line += t;
    textState.x += w;
    // 移除已处理的字符
    textState.content = textState.content.substring(1);
}

/**
 * 新行
 * @param {Object} textState 文字声明
 */
Bitmap.prototype.newLine = function (textState) {
    textState.y += textState.lineHeight;
    textState.x = textState.ox;
    if (textState.y - textState.oy >= textState.height) {
        textState.y -= textState.lineHeight - 5;
        textState.content = "...";
    }
}


/* 值字体 */
Sprite_Gauge.prototype.valueFontFace = function () {
    return $gameSystem.mainFontFace();
};

// ==========工具函数==========

/**
 * 随机取数组中的元素
 * @param {number} amount 数量
 * @returns {Array} result 随机数组
 */
Array.prototype.random = function (amount) {
    // 错误检查
    if (this.length <= 0) {
        console.warn("数组随机抽取函数的数组为空")
        return this;
    }
    if (amount > this.length) {
        console.warn("数组随机抽取函数的抽取数量大于数组长度")
        return this;
    }
    const result = [];
    const availableIndices = Array.from({length: this.length}, (_, i) => i);
    for (let i = 0; i < amount; i++) {
        const randomIndex = Math.floor(Math.random() * availableIndices.length);
        const index = availableIndices[randomIndex];
        result.push(this[index]);
        availableIndices.splice(randomIndex, 1);
    }
    return result;
};

/**
 * 随机打乱数组
 * @returns {Array} result 打乱后的数组
 */
Array.prototype.disarrange = function () {
    for (let i = this.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [this[i], this[j]] = [this[j], this[i]];
    }
    return this;
}